package kr.co.project1.base;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;

public class BaseDao {
	
	@Autowired
	private SqlSessionFactory sqlSessionFactory;
	
	@Autowired
	private SqlSessionTemplate sqlSessionTemplate;

	public SqlSessionFactory getSqlSessionFactory() {
		return sqlSessionFactory;
	}

	public SqlSession getSqlSession() {
		return sqlSessionTemplate;
	}
	
	/**
	 * sql id 로부터 레코드수를 조회하는 sql id 를 가져온다.
	 *
	 * @param sqlId
	 * @return sqlId + "Count" 반환
	 */
	public String getCountSqlId(String sqlId) {
		return sqlId + "Count";
	}

	/**
	 * 페이징처리할 수 있는 메타정보를 담고 있는 PageDto 객체를 가져온다.
	 *
	 * @param sqlId
	 *        조회할 sql id
	 * @param countSqlId
	 *        전체 레코드수를 조회할 sql id, 없으면 sqlId 의 결과 중 처음 엘리먼트에서 totalRecordCount 로 조회한다.
	 * @param requestDto
	 *        쿼리수행 parameter class. 반드시 BaseDto 를 확장한 class여야 한다.
	 * @param curPage
	 *        조회할 페이지번호
	 * @param pageSize
	 *        조회할 페이지의 레코드 수
	 * @return
	 */
	public <T> PageDto<T> selectPageList(String sqlId, String countSqlId, BaseDto requestDto, int curPage, int pageSize) {
		// validate
		int realPage = (curPage < 1) ? 1 : curPage;
		int realPageSize = (pageSize < 1) ? PageDto.DEFAULT_PAGE_SIZE : pageSize;
		BaseDto realRequestDto = (requestDto == null) ? new BaseDto() : requestDto;

		// calculate page data
		realRequestDto.setStartRownum((realPage - 1) * realPageSize + 1);
		realRequestDto.setEndRownum(realPage * realPageSize);

		//
		List<T> resultList = getSqlSession().selectList(sqlId, realRequestDto);

		// 총 레코드 수 totalRecordCount
		int realTotalCount = 0;
		if (countSqlId != null) {
			// countSqlId 가 있으면 쿼리 결과값 사용
			realTotalCount = (Integer)getSqlSession().selectOne(countSqlId, realRequestDto);
		} else if (resultList != null && resultList.size() > 0) {
			// countSqlId 가 없으면 resultList 에서 추출
			realTotalCount = ((BaseDto)resultList.get(0)).getTotalRecordCount();
		}

		//
		return new PageDto<T>(resultList, realPage, realPageSize, realTotalCount);
	}

	/**
	 * 페이징처리할 수 있는 메타정보를 담고 있는 PageDto 객체를 가져온다.
	 *
	 * @param sqlId
	 * @param countSqlId
	 * @param curPage
	 * @param pageSize
	 * @return
	 * @see BaseDao#selectPageList(String, String, BaseDto, int, int)
	 */
	public <T> PageDto<T> selectPageList(String sqlId, String countSqlId, int curPage, int pageSize) {
		return selectPageList(sqlId, countSqlId, (BaseDto)null, curPage, pageSize);
	}

	/**
	 * 페이징처리할 수 있는 메타정보를 담고 있는 PageDto 객체를 가져온다.
	 *
	 * @param sqlId
	 * @param requestDto
	 * @param curPage
	 * @param pageSize
	 * @return
	 * @see BaseDao#selectPageList(String, String, BaseDto, int, int)
	 */
	public <T> PageDto<T> selectPageList(String sqlId, BaseDto requestDto, int curPage, int pageSize) {
		return selectPageList(sqlId, (String)null, requestDto, curPage, pageSize);
	}

	/**
	 * 페이징처리할 수 있는 메타정보를 담고 있는 PageDto 객체를 가져온다.
	 *
	 * @param sqlId
	 * @param curPage
	 * @param pageSize
	 * @return
	 * @see BaseDao#selectPageList(String, String, BaseDto, int, int)
	 */
	public <T> PageDto<T> selectPageList(String sqlId, int curPage, int pageSize) {
		return selectPageList(sqlId, (String)null, (BaseDto)null, curPage, pageSize);
	}

	
}
